/*
ont-space - The ontology-based resource metadata repository
Copyright (c) 2006-2008, Information Eng. Research Unit - Univ. of Alcalá
http://www.cc.uah.es/ie
This library is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the Free
Software Foundation; either version 2.1 of the License, or (at your option)
any later version.
This library is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */
package org.ontspace.util.translator.lom2owl.owl;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;

import org.ieee.ltsc.lom.LOM;
import org.ieee.ltsc.lom.jaxb.lomxml.LOM_JAXBContext;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;

import java.io.*;
import java.util.*;

import com.hp.hpl.jena.ontology.*;
import org.ontspace.owl.MetadataRepositoryImpl;
import org.ontspace.util.translator.lom2owl.Element2OntTranslator;
import org.ontspace.util.translator.lom2owl.LOM2OWLTranslator;

/**
 * LOM2OWLTranslatorImpl class implements the translation between 
 * LOM XML records and OWL representation. 
 */
public class LOM2OWLTranslatorImpl implements LOM2OWLTranslator {

    private LOM lom;
    private OntModel _ont;
    private Individual _instance;
    private MetadataRepositoryImpl _rep;
    private InputStream owlIS;
    private List translators =
            new Vector();
    private String nameSpace =
            "http://www.cc.uah.es/ie/ont/lom-ospace";
    private String confFilePath;
    private PrintWriter fichError;

    public LOM2OWLTranslatorImpl(Individual lo, LOM lomParam,
            MetadataRepositoryImpl rep, OntModel ont,
            String config_file_path, PrintWriter errorWriter) {

        _instance =
                lo;
        lom =
                lomParam;
        _ont =
                ont;
        confFilePath =
                config_file_path;
        _rep =
                rep;
        fichError =
                errorWriter;



    }

    /**
     * This method creates a LOM element from InputStream, 
     * creates a Ontology element with information received from the 
     * initialOntologyFile,creates a list of Translators with information 
     * get from the InputStream configIS and applies that list of Translators 
     * to get the translation. 
     * 
     */
    public void translate() throws Exception {

        prepareTranslators();
        applyTranslators();
    }

    /**
     * This method parse in a LOM object from a LOM-XML file. 
     * 
     */
    protected void createLOMfromInputStream(InputStream metadataIS)
            throws Exception {




    }

    /**
     * This method receives a LOM XML FILE and creates a LOM Object that 
     * stores its content. 
     * 
     */
    private final LOM parseLOMXML(final InputStream is) throws JAXBException {

        final JAXBContext jaxbContext =
                JAXBContext.newInstance(System.getProperty(LOM_JAXBContext.CONTEXT_PATH_PROP,
                LOM_JAXBContext.DEFAULT_CONTEXT_PATH));

        final Unmarshaller unmarshaller =
                jaxbContext.createUnmarshaller();
        unmarshaller.setValidating(false);

        return (LOM) unmarshaller.unmarshal(is);

    }

    /**
     * This Method receives the Configuration InputStream and generates a new 
     * Vector that stores elements of type Element2OntTranslator. 
     *
     */
    protected void prepareTranslators() throws IOException,
            JDOMException {


        // Using SAXBuilder

        SAXBuilder builder =
                new SAXBuilder();
        Document doc =
                builder.build(new File(confFilePath));

        // Get root element

        Element root =
                doc.getRootElement();

        // Getting a List of root Element children

        List mappings =
                root.getChildren("mapping");


        // Create a list of Element2OntTranslator elements.

        System.out.println("*********************** Prepare Translators *******************************");

        Iterator i =
                mappings.iterator();
        while (i.hasNext()) {

            Element mapping =
                    (Element) i.next();
            String elementType =
                    mapping.getChild("type").getTextTrim();
            String elementCategory =
                    mapping.getChild("category").getTextTrim();
            String elementElement =
                    mapping.getChild("element").getTextTrim();
            String elementAttribute =
                    mapping.getChild("attributeName").
                    getTextTrim();


            if (elementType.toString().compareTo("I2LI") == 0) {

                translators.add(new I2LITranslator(elementCategory,
                        elementElement, elementAttribute));
//                System.out.println("Category:" + elementCategory + "Element:" +
//                    elementElement + "Attribute:" + elementAttribute);

            } else if (elementType.toString().compareTo("LS2LS") == 0) {
                translators.add(new LS2LSTranslator(elementCategory,
                        elementElement, elementAttribute));
//                System.out.println("Category:" + elementCategory + "Element:" +
//                    elementElement + "Attribute:" + elementAttribute);

            } else if (elementType.toString().compareTo("S2S") == 0) {
                translators.add(new S2STranslator(elementCategory,
                        elementElement, elementAttribute));
//                 System.out.println("Category:" + elementCategory + "Element:" +
//                    elementElement + "Attribute:" + elementAttribute);

            } else if (elementType.toString().compareTo("VI2S") == 0) {
                translators.add(new VI2STranslator(elementCategory,
                        elementElement, elementAttribute));
//                 System.out.println("Category:" + elementCategory + "Element:" +
//                    elementElement + "Attribute:" + elementAttribute);

            } else if (elementType.toString().compareTo("C2C") == 0) {
                translators.add(new C2CTranslator(elementCategory,
                        elementElement, elementAttribute));
//                 System.out.println("Category:" + elementCategory + "Element:" +
//                    elementElement + "Attribute:" + elementAttribute);


            } else if (elementType.toString().compareTo("DIRECT") == 0) {
                translators.add(new DirectTranslator(elementCategory,
                        elementElement, elementAttribute));
//                 System.out.println("Category:" + elementCategory + "Element:" +
//                    elementElement + "Attribute:" + elementAttribute);

            } else if (elementType.toString().compareTo("MT2S") == 0) {
                translators.add(new MT2STranslator(elementCategory,
                        elementElement, elementAttribute));
//                 System.out.println("Category:" + elementCategory + "Element:" +
//                    elementElement + "Attribute:" + elementAttribute);

            } else if (elementType.toString().compareTo("TR2TR") == 0) {
                translators.add(new TR2TRTranslator(elementCategory,
                        elementElement, elementAttribute));
//                 System.out.println("Category:" + elementCategory + "Element:" +
//                    elementElement + "Attribute:" + elementAttribute);

            } else if (elementType.toString().compareTo("D2D") == 0) {
                translators.add(new D2DTranslator(elementCategory,
                        elementElement, elementAttribute));
//                 System.out.println("Category:" + elementCategory + "Element:" +
//                    elementElement + "Attribute:" + elementAttribute);

            } else if (elementType.toString().compareTo("MD2MD") == 0) {
                translators.add(new MD2MDTranslator(elementCategory,
                        elementElement, elementAttribute));
//                 System.out.println("Category:" + elementCategory + "Element:" +
//                    elementElement + "Attribute:" + elementAttribute);

            } else if (elementType.toString().compareTo("E2E") == 0) {
                translators.add(new E2ETranslator(elementCategory,
                        elementElement, elementAttribute));
//                 System.out.println("Category:" + elementCategory + "Element:" +
//                    elementElement + "Attribute:" + elementAttribute);

            } else if (elementType.toString().compareTo("CL2CL") == 0) {
                translators.add(new CL2CLTranslator(elementCategory,
                        elementElement, elementAttribute));
//                 System.out.println("Category:" + elementCategory + "Element:" +
//                    elementElement + "Attribute:" + elementAttribute);

            } else if (elementType.toString().compareTo("R2R") == 0) {
                translators.add(new R2RTranslator(elementCategory,
                        elementElement, elementAttribute));
//                 System.out.println("Category:" + elementCategory + "Element:" +
//                    elementElement + "Attribute:" + elementAttribute);

            } else if (elementType.toString().compareTo("A2A") == 0) {
                translators.add(new A2ATranslator(elementCategory,
                        elementElement, elementAttribute));
//                 System.out.println("Category:" + elementCategory + "Element:" +
//                    elementElement + "Attribute:" + elementAttribute);

            }





        }

        System.out.println("***************************************************************************");


    }

    /**
     * This Method receives the LOM Object, the Ontology object and the 
     * Instance object.
     * It looks over the translators List and invokes the appropiate 
     * elementTranslator.
     * 
     * The modified ontology is received and it is stored in the indicated File. 
     */
    protected void applyTranslators()
            throws IOException, JDOMException {

        Iterator t =
                translators.iterator();
        while (t.hasNext()) {
            Element2OntTranslator el =
                    (Element2OntTranslator) t.next();

            el.apply(lom, _ont, _instance, nameSpace, fichError);
        }
//        ontology.write(ontologyOS,"RDF/XML");        

    }
}
